package com.agileai.miscdp.hotweb.ui.actions.query;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;

import com.agileai.miscdp.hotweb.domain.query.QueryFuncModel;
import com.agileai.miscdp.hotweb.generator.query.QMHandlerCfgGenerator;
import com.agileai.miscdp.hotweb.generator.query.QMHandlerGenerator;
import com.agileai.miscdp.hotweb.generator.query.QMJspPagGenerator;
import com.agileai.miscdp.hotweb.generator.query.QMServiceCfgGenerator;
import com.agileai.miscdp.hotweb.generator.query.QMServiceClassGenerator;
import com.agileai.miscdp.hotweb.generator.query.QMServiceInterfaceGenerator;
import com.agileai.miscdp.hotweb.generator.query.QMSqlMapCfgGenerator;
import com.agileai.miscdp.hotweb.generator.query.QMSqlMapGenerator;
import com.agileai.miscdp.hotweb.ui.actions.BaseGenCodesAction;
import com.agileai.miscdp.hotweb.ui.dialogs.CodeGenConfigDialog;
import com.agileai.miscdp.hotweb.ui.editors.query.QueryModelEditor;
import com.agileai.miscdp.hotweb.ui.editors.query.QueryModelEditorContributor;
import com.agileai.miscdp.util.DialogUtil;
import com.agileai.miscdp.util.MiscdpUtil;
import com.agileai.domain.KeyNamePair;
import com.agileai.util.FileUtil;
import com.agileai.util.StringUtil;
/**
 * 代码生成动作
 */
public class QMGenCodesAction extends BaseGenCodesAction{
	private static final String GenOptionSection = "QueryModelEditor.GeneratorOption";
	
	public QMGenCodesAction() {
		super();
	}
	public void setContributor(QueryModelEditorContributor contributor) {
		this.contributor = contributor;
	}
	public void run() {
		QueryModelEditor modelEditor = (QueryModelEditor)this.getModelEditor();
    	String listJspName = modelEditor.getQMBasicConfigPage().getQMExtendAttribute().getListJspNameText().getText();
    	if (StringUtil.isNullOrEmpty(listJspName)){
    		String listJspCheckNullMsg = MiscdpUtil.getIniReader().getValue("QueryModelEditor","ListJspCheckNullMsg");
    		DialogUtil.showInfoMessage(listJspCheckNullMsg);
    		return;
    	}
    	String recordIds = modelEditor.getQMDetailJspCfgPage().getRecordIdsText().getText();
    	if (StringUtil.isNullOrEmpty(recordIds)){
    		String recordIdsCheckNullMsg = MiscdpUtil.getIniReader().getValue("QueryModelEditor","RecordIdsCheckNullMsg");
    		DialogUtil.showInfoMessage(recordIdsCheckNullMsg);
    		return;
    	}
    	Shell shell = modelEditor.getSite().getShell();
    	if (modelEditor.isDirty()){
    		String confirmTitle = MiscdpUtil.getIniReader().getValue("DialogInfomation","ConfirmTitle");
    		String confirmMsg = MiscdpUtil.getIniReader().getValue("DialogInfomation","IsSaveFirst");
    		boolean saveFirst = MessageDialog.openConfirm(shell, confirmTitle, confirmMsg);
    		if (saveFirst){
    			modelEditor.doSave(new NullProgressMonitor());
    		}else{
    			return;
    		}
    	}
    	funcModel = modelEditor.buildFuncModel();		
		CodeGenConfigDialog configDialog = new CodeGenConfigDialog(shell);
		List<KeyNamePair> inputGenList = new ArrayList<KeyNamePair>();
		inputGenList = MiscdpUtil.getIniReader().getList(GenOptionSection);
		configDialog.setInputGenList(inputGenList);
		configDialog.open();
		if (configDialog.getReturnCode() != Dialog.OK){
			return;
		}
		genertorMap = configDialog.getSelectedKeyNamePairs();
    	
		IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
		try {
			String projectName = funcModel.getProjectName();
			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
			progressService.runInUI(progressService,this,project);
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public void run(IProgressMonitor monitor) throws InvocationTargetException,
			InterruptedException {
		monitor.beginTask("init model values:", 1000);
		monitor.subTask("set model values....");
		monitor.worked(50);
		
		File xmlFile = getXmlFile();
		String projectName = funcModel.getProjectName();
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
		String srcDir = project.getLocation().toString()+"/src";
		QueryFuncModel queryFuncModel = (QueryFuncModel)funcModel;
		String sqlMapFile = queryFuncModel.getSqlMapFile();
		File sqlMap = new File(sqlMapFile);
		File parentFile = sqlMap.getParentFile();
		if (!parentFile.exists()){
			parentFile.mkdirs();
		}
		String fileName = sqlMap.getName();
		String sqlNameSpace = fileName.substring(0,fileName.length()-4);
		queryFuncModel.setSqlNameSpace(sqlNameSpace);
		
		if (genertorMap.containsKey(GEN_OPTION_JSPPAGE)){
			monitor.subTask("generating jsp files....");
			monitor.worked(200);
			
			QMJspPagGenerator sMJspPagGenerator = new QMJspPagGenerator();
			sMJspPagGenerator.setXmlFile(xmlFile);
			String listJspName = project.getLocation().toString()+"/WebRoot/jsp/"+((QueryFuncModel)funcModel).getListJspName();
	    	String detailJspName = project.getLocation().toString()+"/WebRoot/jsp/"+((QueryFuncModel)funcModel).getDetailJspName();
			sMJspPagGenerator.setListJspFile(listJspName);
			sMJspPagGenerator.setDetailJspFile(detailJspName);
			sMJspPagGenerator.setShowDetail(queryFuncModel.isShowDetail());
			sMJspPagGenerator.generate();
		}

		if (genertorMap.containsKey(GEN_OPTION_SQLMAP_INDEX)){
			monitor.subTask("generating SqlMap Index files....");
			monitor.worked(250);
			QMSqlMapCfgGenerator sMSqlMapGenerator = new QMSqlMapCfgGenerator();
			String abstSqlMapCfgPath = project.getLocation().toString()+"/src/SqlMapConfig.xml";
			sMSqlMapGenerator.setConfigFile(abstSqlMapCfgPath);
			sMSqlMapGenerator.setSqlMapFileName(sqlNameSpace);
			sMSqlMapGenerator.generate();
		}
		
		if (genertorMap.containsKey(GEN_OPTION_SQLMAP_DEFINE)){
			monitor.subTask("generating SqlMap files....");
			monitor.worked(300);
			QMSqlMapGenerator sMSqlMapGenerator = new QMSqlMapGenerator();
			String[] rsIds = ((QueryFuncModel)funcModel).getRsIdColumns().toArray(new String[0]);
			sMSqlMapGenerator.setRsIds(rsIds);
			String findRecordsSql = funcModel.getListSql();
			sMSqlMapGenerator.setFindRecordsSql(findRecordsSql);
	    	sqlMapFile = ((QueryFuncModel)funcModel).getSqlMapFile();
	    	sMSqlMapGenerator.setSqlMapFile(sqlMapFile);
	    	sMSqlMapGenerator.setFuncModel((QueryFuncModel)funcModel);
			sMSqlMapGenerator.generate();
		}

		if (genertorMap.containsKey(GEN_OPTION_SERVICE_CONFIG)){
			monitor.subTask("generating Service config files....");
			monitor.worked(500);
			QMServiceCfgGenerator sMServiceCfgGenerator = new QMServiceCfgGenerator();
			String abstServiceCfgPath = project.getLocation().toString()+"/src/ServiceContext.xml";
			sMServiceCfgGenerator.setConfigFile(abstServiceCfgPath);
			sMServiceCfgGenerator.setFuncModel((QueryFuncModel)funcModel);
			sMServiceCfgGenerator.generate();
		}
		
		if (genertorMap.containsKey(GEN_OPTION_HANDLER_CONFIG)){
			monitor.subTask("generating Handler config files....");
			monitor.worked(600);
			QMHandlerCfgGenerator sMHandlerCfgGenerator = new QMHandlerCfgGenerator();
			String abstHandlerCfgPath = project.getLocation().toString()+"/src/HandlerContext.xml";
			sMHandlerCfgGenerator.setConfigFile(abstHandlerCfgPath);
			sMHandlerCfgGenerator.setFuncModel((QueryFuncModel)funcModel);
			sMHandlerCfgGenerator.generate();
		}
		
		if (genertorMap.containsKey(GEN_OPTION_HANDLER_CLASS)){
			monitor.subTask("generating Handler java files....");
			monitor.worked(700);
			QMHandlerGenerator sMHandlerGenerator = new QMHandlerGenerator();
			sMHandlerGenerator.setSrcPath(srcDir);
			String listHandlerClassName = queryFuncModel.getListHandlerClass();
			sMHandlerGenerator.setListHandlerClassName(listHandlerClassName);
			String editHandlerClassName = queryFuncModel.getEditHandlerClass();
			sMHandlerGenerator.setDetailHandlerClassName(editHandlerClassName);
			sMHandlerGenerator.setShowDetail(queryFuncModel.isShowDetail());
			sMHandlerGenerator.setXmlFile(xmlFile);
			sMHandlerGenerator.generate();
		}

		if (genertorMap.containsKey(GEN_OPTION_SERVICE_IMPL)){
			monitor.subTask("generating Service Impl java files....");
			monitor.worked(800);
			QMServiceClassGenerator sMServiceClassGenerator = new QMServiceClassGenerator();
			String implFullClassName = funcModel.getImplClassName();
			File implJavaFile = FileUtil.createJavaFile(srcDir, implFullClassName);
			String implJavaFilePath = implJavaFile.getAbsolutePath();
			sMServiceClassGenerator.setJavaFile(implJavaFilePath);
			sMServiceClassGenerator.setXmlFile(xmlFile);
			sMServiceClassGenerator.generate();
			
			try {
				MiscdpUtil.getJavaFormater().format(implJavaFilePath, sMServiceClassGenerator.getCharencoding());
			} catch (IOException e1) {
				e1.printStackTrace();
				throw new InvocationTargetException(e1);
			}
		}
		
		if (genertorMap.containsKey(GEN_OPTION_SERVICE_INTERFACE)){
			monitor.subTask("generating Service Interface java files....");
			monitor.worked(900);
			QMServiceInterfaceGenerator sMServiceInterfaceGenerator = new QMServiceInterfaceGenerator();
			String interfaceClassName = funcModel.getInterfaceName();
			File interfaceJavaFile = FileUtil.createJavaFile(srcDir, interfaceClassName);
			String interfaceJavaFilePath = interfaceJavaFile.getAbsolutePath();
			sMServiceInterfaceGenerator.setJavaFile(interfaceJavaFilePath);
			sMServiceInterfaceGenerator.setXmlFile(xmlFile);
			sMServiceInterfaceGenerator.generate();
			
			try {
				MiscdpUtil.getJavaFormater().format(interfaceJavaFilePath, sMServiceInterfaceGenerator.getCharencoding());
			} catch (IOException e1) {
				e1.printStackTrace();
				throw new InvocationTargetException(e1);
			}
		}
		
		try {
			project.refreshLocal(IResource.DEPTH_INFINITE, null);
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}
}
